import ROOT
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.subplots as sub
class my_KDE:
def __init__(self, sample, bandwidth=1.0):
self.sample = sample
self.bandwidth = bandwidth
def pdf(self, x):
return [(1 / (2 * np.pi) ** 0.5) * np.exp(-(i - self.sample) ** 2 / (2 * self.bandwidth ** 2)).mean() / self.bandwidth for i in x]
def pdf_max(self, x0, lam, eps):
x1 = x0 + lam * (1 / (2 * np.pi) ** 0.5) * (-np.exp(-(x0 - self.sample) ** 2 / (2 * self.bandwidth ** 2)) \
* (x0 - self.sample)).mean() / self.bandwidth ** 3
while abs(x1 - x0) > eps:
x0 = x1
x1 = x0 + lam * (1 / (2 * np.pi) ** 0.5) * (-np.exp(-(x0 - self.sample) ** 2 / (2 * self.bandwidth ** 2)) \
* (x0 - self.sample)).mean() / self.bandwidth ** 3
return x1
def print_err(a, a_err, vis=True):
a = np.array([a]).flatten()
a_err = np.array([a_err]).flatten()
val = np.zeros_like(a)
sig = np.zeros_like(a_err)
for i in range(a.size):
val[i] = np.round(a[i], decimals = round(1 * (np.trunc(np.log10(a_err[i]) < 0)) - np.trunc(np.log10(a_err[i]))))
sig[i] = np.round(a_err[i], decimals = round(1 * (np.trunc(np.log10(a_err[i]) < 0)) - np.trunc(np.log10(a_err[i]))))
if vis: print(val[i], '\pm', sig[i])
return val, sig
Изучение шума SiPm и определение величины перенапряжения¶
U = np.arange(25.5, 29.5, 0.5)
for i in U:
rdf = ROOT.RDataFrame('TD', 'data/{}.root'.format(int(i * 100)))
data = pd.DataFrame(rdf.AsNumpy())
A = [data['Par.A'][j] for j in range(data.shape[0])]
chan = [data['Par.chan'][j] for j in range(data.shape[0])]
tok = [data['Par.tok'][j] for j in range(data.shape[0])]
type = [data['Par.type'][j] for j in range(data.shape[0])]
user = [data['Par.user'][j] for j in range(data.shape[0])]
I = data['Integral']
pd.DataFrame({'A': A, 'chan': chan, 'tok': tok, 'type': type, 'user': user, 'I': I}).to_csv('data/{}.csv'.format(int(i * 100)), index=False)
x = np.linspace(0, 1000, 2000)
max1 = [69.34, 64.03, 90.92, 111.96, 134.09, 155.23, 179.88, 205.32]
for num, val in enumerate(U):
data = pd.read_csv('data/{}.csv'.format(int(val * 100)))
mask = (data['chan'] == 53 * 64 + 16) * (data['type'] == 0)
max1[num] = my_KDE(data['I'][mask], bandwidth=2.5 + num / 3).pdf_max(max1[num], 10, 0.000001)
max2 = [117.33, 171.46, 216.39, 265.09, 306.74, 360.07, 403.32]
for num, val in enumerate(U[1:]):
data = pd.read_csv('data/{}.csv'.format(int(val * 100)))
mask = (data['chan'] == 53 * 64 + 16) * (data['type'] == 0)
max2[num] = my_KDE(data['I'][mask], bandwidth=2.5 + (num + 1) / 3).pdf_max(max2[num], 10, 0.00001)
fig = sub.make_subplots(rows=U.size, cols=1, subplot_titles=['U={} В'.format(i) for i in U])
for num, val in enumerate(U):
data = pd.read_csv('data/{}.csv'.format(int(val * 100)))
mask = (data['chan'] == 53 * 64 + 16) * (data['type'] == 0)
model = my_KDE(data['I'][mask], bandwidth=2.5 + num / 3)
y = model.pdf(x)
fig.add_traces(go.Scattergl(x=x, y=y, marker=dict(color='red'), showlegend=False), num + 1, 1)
fig.add_traces(go.Histogram(x=data['I'][mask], xbins=dict(start=0, end=1000, size=4), marker=dict(color='blue', opacity=0.3),
autobinx=False, histnorm='probability density', showlegend=False), num + 1, 1)
fig.add_traces(go.Scatter(y=model.pdf([max1[num]]), x=[max1[num]],
name='', marker=dict(size=7, color='green'), showlegend=False),
num + 1, 1)
fig.add_annotation(x=max1[num], y=model.pdf([max1[num]])[0],
xref='x{}'.format(num + 1), yref='y{}'.format(num + 1),
text='max at ' + str(np.round(max1[num], decimals=4)),
showarrow=True, arrowhead=2, arrowsize=1, arrowwidth=2,
arrowcolor="#636363", ax=50, ay=-50, bordercolor="#c7c7c7", borderwidth=2, borderpad=4, bgcolor="#ff7f0e")
if num != 0:
fig.add_traces(go.Scatter(y=model.pdf([max2[num - 1]]), x=[max2[num - 1]],
name='', marker=dict(size=7, color='green'), showlegend=False),
num + 1, 1)
fig.add_annotation(x=max2[num - 1], y=model.pdf([max2[num - 1]])[0],
xref='x{}'.format(num + 1), yref='y{}'.format(num + 1),
text='max at ' + str(np.round(max2[num - 1], decimals=4)),
showarrow=True, arrowhead=2, arrowsize=1, arrowwidth=2,
arrowcolor="#636363", ax=50, ay=-50, bordercolor="#c7c7c7", borderwidth=2, borderpad=4, bgcolor="#ff7f0e")
fig.update_layout(width=950, height=3000,
xaxis1=dict(range=(0, 1000)),
xaxis2=dict(range=(0, 1000)),
xaxis3=dict(range=(0, 1000)),
xaxis4=dict(range=(0, 1000)),
xaxis5=dict(range=(0, 1000)),
xaxis6=dict(range=(0, 1000)),
xaxis7=dict(range=(0, 1000)),
xaxis8=dict(range=(0, 1000)),
title='Поиск однопиксельных и двухпиксельных пиков ',
margin=dict(l=50, r=50, b=40, t=90))
fig.show('notebook')
При 25.5 В пики сливаются и искажают зависимость. Будем использовать только напряжения начиная с 26 В.
max1 = max1[1:]
U = U[1:]
fig = sub.make_subplots(rows=1, cols=2, subplot_titles=['Однопиксельные', 'Двухпиксельные'])
fig.add_traces(go.Scattergl(x=U, y=max1, mode='markers', marker=dict(color='blue'), name='Максимумы', legendgroup=1), 1, 1)
k1, err1 = np.polyfit(U, max1, deg=1, cov=True)
fig.add_traces(go.Scattergl(x=U, y=k1[0] * U + k1[1], mode='lines', marker=dict(color='red'), legendgroup=2, name='Аппроксимация'), 1, 1)
fig.add_traces(go.Scattergl(x=U, y=max2, mode='markers', marker=dict(color='blue'), showlegend=False, name='Максимумы', legendgroup=1), 1, 2)
k2, err2 = np.polyfit(U, max2, deg=1, cov=True)
fig.add_traces(go.Scattergl(x=U, y=k2[0] * U + k2[1], mode='lines', marker=dict(color='red'), legendgroup=2, showlegend=False, name='Аппроксимация'), 1, 2)
fig.update_layout(width=950, height=470,
legend=dict(orientation='v'),
title='Зависимость максимумов от напряжения напряжения',
xaxis1=dict(title='U, В'),
xaxis2=dict(title='U, В'),
margin=dict(l=50, r=50, b=40, t=90))
fig.show('notebook')
D = np.array(k1[1] / k1[0] ** 2, -1 / k1[1])
U_break_1, U_break_err_1 = print_err(-k1[1] / k1[0], np.abs(D.dot(err1).dot(D)) ** 0.5, vis=False)
print('Напряжение пробоя по однопиксельным максимумам U = {} ± {} В'.format(U_break_1[0], U_break_err_1[0]))
D = np.array(k2[1] / k2[0] ** 2, -1 / k2[1])
U_break_2, U_break_err_2 = print_err(-k2[1] / k2[0], np.abs(D.dot(err2).dot(D)) ** 0.5, vis=False)
print('Напряжение пробоя по двухпиксельным максимумам U = {} ± {} В'.format(U_break_2[0], U_break_err_2[0]))
U_break = (U_break_1[0] / U_break_err_1[0] ** 2 + U_break_2[0] / U_break_err_2[0] ** 2) / (1 / U_break_err_1[0] ** 2 + 1 / U_break_err_2[0] ** 2)
U_break_err = 1 / (1 / U_break_err_1[0] ** 2 + 1 / U_break_err_2[0] ** 2) ** 0.5
U_break, U_break_err = print_err(U_break, U_break_err, vis=False)
print('Напряжение пробоя U = {} ± {} В'.format(U_break[0], U_break_err[0]))
cr = []
for num, val in enumerate(U):
data = pd.read_csv('data/{}.csv'.format(int(val * 100)))
mask = (data['chan'] == 53 * 64 + 16) * (data['type'] == 0)
cr.append(data['I'][mask].mean() / max1[num])
fig = go.Figure()
fig.add_traces(go.Scattergl(x=U, y=cr, mode='markers', marker=dict(color='blue'), name='Crosstalk'))
k, err = np.polyfit(U, cr, deg=1, cov=True)
x = np.linspace(U.min(), U.max(), 100)
fig.add_traces(go.Scattergl(x=x, y=k[0] * x + k[1], mode='lines', marker=dict(color='red'), name='Аппроксимация'))
fig.update_layout(width=950, height=850,
legend=dict(orientation='v'),
title='Зависимость crosstalk от напряжения напряжения',
xaxis1=dict(title='U, В'),
xaxis2=dict(title='U, В'),
margin=dict(l=50, r=50, b=40, t=60))
fig.show('notebook')
Наблюдение сигналов от космических мюонов¶
rdf = ROOT.RDataFrame('TD', 'data/million_hitov-4.root')
data = pd.DataFrame(rdf.AsNumpy())
I16 = [data['Par.I'][j][16] for j in range(data.shape[0])]
I17 = [data['Par.I'][j][17] for j in range(data.shape[0])]
I18 = [data['Par.I'][j][18] for j in range(data.shape[0])]
pd.DataFrame({'I[16]': I16, 'I[17]': I17, 'I[18]': I18}).to_csv('data/million_hitov-4.csv', index=False)
data = pd.read_csv('data/million_hitov-4.csv')
threshold = 1600
fig = go.Figure()
fig.add_traces(go.Histogram(x=data['I[16]'][(data['I[17]'] > threshold) * (data['I[18]'] > threshold)],
xbins=dict(start=0, end=25000, size=1000), autobinx=False, opacity=0.7))
fig.update_layout(width=950, height=550,
title='Срабатывание 17 и 18',
margin=dict(l=50, r=50, b=40, t=60),
xaxis=dict(range=[0, 25000]))
fig.show('notebook')
print('Зарегистрированно {} событий'.format(((data['I[17]'] > threshold) * (data['I[18]'] > threshold)).sum()))
fig = go.Figure()
fig.add_traces(go.Histogram(x=data['I[17]'][(data['I[16]'] > threshold) * (data['I[18]'] > threshold)],
xbins=dict(start=0, end=25000, size=1000), autobinx=False, opacity=0.7))
fig.update_layout(width=950, height=550,
title='Срабатывание 16 и 18',
margin=dict(l=50, r=50, b=40, t=60),
xaxis=dict(range=[0, 25000]))
fig.show('notebook')
print('Зарегистрированно {} событий'.format(((data['I[16]'] > threshold) * (data['I[18]'] > threshold)).sum()))
fig = go.Figure()
fig.add_traces(go.Histogram(x=data['I[18]'][(data['I[17]'] > threshold) * (data['I[16]'] > threshold)],
xbins=dict(start=0, end=25000, size=1000), autobinx=False, opacity=0.7))
fig.update_layout(width=950, height=550,
title='Срабатывание 16 и 17',
margin=dict(l=50, r=50, b=40, t=60),
xaxis=dict(range=[0, 25000]))
fig.show('notebook')
print('Зарегистрированно {} событий'.format(((data['I[16]'] > threshold) * (data['I[17]'] > threshold)).sum()))